using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
using System.Reflection;

using Softelvdm.SftTreeNET;
using Softelvdm.Controls;

namespace WindowsApplication1 {
    public partial class EditSample1 : Form {
        public EditSample1() {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e) {
            // This sample demonstrates cell editing using edit controls and combo boxes.
            // To prepare for this sample, create a new project with a blank form and add
            // a SftTree/NET control named sftTree1.
            // In addition, add a textbox named textbox1 and a combo box named comboBox1.
            sftTree1.Initializing = true;
            sftTree1.Columns.Count = 3;
            for (int i = 0 ; i < 100 ; ++i) {
                ItemClass item = sftTree1.ItemCollection.Add(new string[] {"Can't", "Text", "Combo"} );
            }    
            sftTree1.Columns.MakeOptimal(0, false);
            sftTree1.RecalcHorizontalExtent();
            sftTree1.Initializing = false;
        }

        private void sftTree1_EditAllowed(object sender, Softelvdm.SftTreeNET.EditAllowedEventArgs e) {
            Debug.Write("** EditAllowed");
            DumpValues(e);
             if (e.Cell.ColumnIndex == 0) // Can't edit the first column
                 e.Allowed = false;
        }

        private void sftTree1_EditSetup(object sender, Softelvdm.SftTreeNET.EditSetupEventArgs e) {
            Debug.Write("** EditSetup");
            DumpValues(e);

            if (e.Cell.ColumnIndex == 1) {
                // We use a textbox for column 1 (remember, column 0 is not editable,
                // because of the EditAllowed event
                // set all textbox properties
                textBox1.Parent = sftTree1;     // make the tree control the parent window

                textBox1.Text = e.Cell.Text;
                int h = textBox1.Height;

                Rectangle r = e.rCell;
                // limit the control to the left (and only) pane
                r.Intersect(sftTree1.Splitter.Left.ItemsArea);
                int vOffs = (r.Size.Height - textBox1.Height) / 2;
                textBox1.Location = new Point(r.Location.X, r.Location.Y + vOffs);
                textBox1.Width = r.Width;

                // make it visible and enable it
                textBox1.Enabled = true;
                textBox1.Visible = true;

                // off we go!
                textBox1.BringToFront();
                textBox1.Focus();
                e.EditControl = textBox1;
            } else if (e.Cell.ColumnIndex == 2) {
                // We use a combobox for column 2
                comboBox1.Parent = sftTree1;

                comboBox1.Items.Clear();
                comboBox1.Items.AddRange(new string[] { "Selection 1", "Selection 2", "Selection 3", "Selection 4", "Selection 5" });

                comboBox1.Text = e.Cell.Text;
                int h = comboBox1.Height;

                Rectangle r = e.rCell;
                // limit the control to the left (and only) pane
                r.Intersect(sftTree1.Splitter.Left.ItemsArea);
                int vOffs = (r.Size.Height - comboBox1.Height) / 2;
                comboBox1.Location = new Point(r.Location.X, r.Location.Y + vOffs);
                comboBox1.Width = r.Width;

                // make it visible and enable it
                comboBox1.Enabled = true;
                comboBox1.Visible = true;

                // off we go!
                comboBox1.BringToFront();
                comboBox1.Focus();
                e.EditControl = comboBox1;
            }
        }
        private void sftTree1_EditValidate(object sender, EditValidateEventArgs e) {
            if (e.EditControl is TextBox) {
                if (textBox1.Text == "") { // you MUST enter something
                    e.Valid = false;
                    MessageBox.Show("Cell text can't be empty in this example.");
                }
            } else if (e.EditControl is ComboBox) {
                if (comboBox1.Text == "") { // you MUST select something
                    e.Valid = false;
                    MessageBox.Show("Cell text can't be empty in this example.");
                }
            }
        }
        private void sftTree1_EditEnded(object sender, Softelvdm.SftTreeNET.EditEndedEventArgs e) {

            if (e.EditControl is TextBox) {
                // save the new cell text if necessary
                if (e.SaveValue)
                    e.Cell.Text = textBox1.Text;

                // hide the text box and make the form the control's parent
                textBox1.Visible = false;
                textBox1.Enabled = false;
                textBox1.Parent = sftTree1.Parent;
            } else if (e.EditControl is ComboBox) {
                // save the new cell text if necessary
                if (e.SaveValue)
                    e.Cell.Text = comboBox1.Text;

                // hide the text box and make the form the control's parent
                comboBox1.Visible = false;
                comboBox1.Enabled = false;
                comboBox1.Parent = sftTree1.Parent;
            }            
            Debug.Write("** EditEnded");
            DumpValues(e);

        }
        private void sftTree1_ItemClick(object sender, Softelvdm.SftTreeNET.ItemClickEventArgs e) {
            Debug.Write("** ItemClick");
            DumpValues(e);
            if (e.Area == ItemClickAreaEnum.CellSel)
                e.Cell.Edit();  // Start cell editing
        }


        // Handle all the cell navigation for the text box here 
        private void textBox1_KeyDown(object sender, KeyEventArgs e) {
            if (e.KeyCode == Keys.Up) {
                sftTree1.EditNavigate(EditNavigateEnum.Up);
                e.Handled = true;
            } else if (e.KeyCode == Keys.Down) {
                sftTree1.EditNavigate(EditNavigateEnum.Down);
                e.Handled = true;
            } else if (e.KeyCode == Keys.Left && (e.Modifiers & Keys.Control) != 0) { // Ctrl+Left
                sftTree1.EditNavigate(EditNavigateEnum.Left);
                e.Handled = true;
            } else if (e.KeyCode == Keys.Right && (e.Modifiers & Keys.Control) != 0) { // Ctrl+Right
                sftTree1.EditNavigate(EditNavigateEnum.Right);
                e.Handled = true;
            } else if (e.KeyCode == Keys.Home && (e.Modifiers & Keys.Control) != 0) { // Ctrl+Home
                sftTree1.EditNavigate(EditNavigateEnum.Home);
                e.Handled = true;
            } else if (e.KeyCode == Keys.End && (e.Modifiers & Keys.Control) != 0) { // Ctrl+End
                sftTree1.EditNavigate(EditNavigateEnum.End);
                e.Handled = true;
            } else if (e.KeyCode == Keys.Tab && (e.Modifiers & Keys.Shift) != 0) { // Shift+Tab
                sftTree1.EditNavigate(EditNavigateEnum.Left);
                e.Handled = true;
            } else if (e.KeyCode == Keys.Tab && (e.Modifiers & Keys.Shift) == 0) { // Tab
                sftTree1.EditNavigate(EditNavigateEnum.Right);
                e.Handled = true;
            } else if (e.KeyCode == Keys.Escape) { // ESC
                sftTree1.EndEdit(false);
                e.Handled = true;
            } else if (e.KeyCode == Keys.Return) { // Return
                sftTree1.EndEdit(true);
                e.Handled = true;
            }
        }

        // Textboxes normally don't want Tab and Escape keys, so we enable these here
        private void textBox1_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e) {
            if (e.KeyCode == Keys.Tab)
                e.IsInputKey = true;
            else if (e.KeyCode == Keys.Escape)
                e.IsInputKey = true;
        }

        private void comboBox1_KeyDown(object sender, KeyEventArgs e) {
            if (e.KeyCode == Keys.Up && (e.Modifiers & Keys.Control) != 0) { // Ctrl+Up
                sftTree1.EditNavigate(EditNavigateEnum.Up);
                e.Handled = true;
            } else if (e.KeyCode == Keys.Down && (e.Modifiers & Keys.Control) != 0) { // Ctrl+Down
                sftTree1.EditNavigate(EditNavigateEnum.Down);
                e.Handled = true;
            } else if (e.KeyCode == Keys.Left && (e.Modifiers & Keys.Control) != 0) { // Ctrl+Left
                sftTree1.EditNavigate(EditNavigateEnum.Left);
                e.Handled = true;
            } else if (e.KeyCode == Keys.Right && (e.Modifiers & Keys.Control) != 0) { // Ctrl+Right
                sftTree1.EditNavigate(EditNavigateEnum.Right);
                e.Handled = true;
            } else if (e.KeyCode == Keys.Home && (e.Modifiers & Keys.Control) != 0) { // Ctrl+Home
                sftTree1.EditNavigate(EditNavigateEnum.Home);
                e.Handled = true;
            } else if (e.KeyCode == Keys.End && (e.Modifiers & Keys.Control) != 0) { // Ctrl+End
                sftTree1.EditNavigate(EditNavigateEnum.End);
                e.Handled = true;
            } else if (e.KeyCode == Keys.Tab && (e.Modifiers & Keys.Shift) != 0) { // Shift+Tab
                sftTree1.EditNavigate(EditNavigateEnum.Left);
                e.Handled = true;
            } else if (e.KeyCode == Keys.Tab && (e.Modifiers & Keys.Shift) == 0) { // Tab
                sftTree1.EditNavigate(EditNavigateEnum.Right);
                e.Handled = true;
            } else if (e.KeyCode == Keys.Escape && !comboBox1.DroppedDown) { // ESC (only if dropdown is not showing)
                sftTree1.EndEdit(false);
                e.Handled = true;
            } else if (e.KeyCode == Keys.Return && !comboBox1.DroppedDown) { // Return (only if dropdown is not showing)
                sftTree1.EndEdit(true);
                e.Handled = true;
            }
        }

        // Comboboxes normally don't want Tab and Escape keys, so we enable these here
        private void comboBox1_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e) {
            if (e.KeyCode == Keys.Tab)
                e.IsInputKey = true;
            else if (e.KeyCode == Keys.Escape && !comboBox1.DroppedDown) // (only if dropdown is not showing)
                e.IsInputKey = true;
        }


        // This is a small helper routine to show all properties and fields of an object
        private void DumpValues(object o) {
            PropertyInfo[] api = o.GetType().GetProperties();
            foreach (PropertyInfo pi in api)
                Debug.Write(" " + pi.Name + " " + pi.GetValue(o, new object[] { }));
            FieldInfo[] afi = o.GetType().GetFields();
            foreach (FieldInfo fi in afi)
                Debug.Write(" " + fi.Name + " " + fi.GetValue(o));
            Debug.WriteLine("");
        }
    }
}